using System;
using System.Configuration;
using System.Collections.Generic;
using System.Text;
using RoardersAgentSim.Map;
using System.IO;
using RoardersAgentSim.Agent;

namespace RoardersAgentSim
{
    /// <summary>
    /// class definition of the general Environment and scenario studied
    /// </summary>
    public class Environment
    {
        #region private input attributes
        /// <summary>
        /// The current map
        /// </summary>
        private FullMap _currentMap;
        #endregion
        #region public attributes
        /// <summary>
        /// Reference to the full map
        /// </summary>
        public FullMap CurrentMap
        {
            get { return _currentMap; }
        }
        /// <summary>
        /// // time when disaster occurs
        /// </summary>
        public int tau_0
        {
            get;
            private set;
        }
        /// <summary>
        /// time for evacuation
        /// </summary>
        public int tau_z
        {
            get;
            private set;
        }
        /// <summary>
        /// current simulation time (time step) - set from Simulation
        /// </summary>
        public int time
        {
            get;
            set;
        }
        #endregion

        // ---------------------------------------------------
        #region constructor
        /// <summary>
        /// Implicit constructor
        /// </summary>
        public Environment(FullMap map)
        {
            _currentMap = map;
            if (!_currentMap.Initialised)
                throw new Exception("not initialised map");
        }
        #endregion
        /// <summary>
        /// define the scenario attributes
        /// </summary>
        public void DefineScenarioAttributes()
        {
            tau_0 = int.Parse(ConfigurationManager.AppSettings["TAU0"]);
            tau_z = int.Parse(ConfigurationManager.AppSettings["TAUZ"]);
            LogHelper.LogStep("Scenario attributes defined.");
        }
        /// <summary>
        /// Get the specified node
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        internal Node GetNode(string nodeID)
        {
            return this._currentMap.Nodes.Find(x => string.Compare(x.NodeID, nodeID) == 0);
        }
        /// <summary>
        /// save the map state in a file
        /// </summary>
        /// <param name="popMGR"></param>
        internal void SaveState(PopulationManager popMGR)
        {
            string directory = ConfigurationManager.AppSettings["output"];
            if(!directory.EndsWith(@"\"))
                directory += @"\";
            string fileName = string.Format("_{0}.{1}", DateTime.Now.ToString("yyyyMMddHHmm"),"txt");
            StreamWriter file = new StreamWriter(directory + "ENVIRONMENT_NODES"+fileName,true);
            file.WriteLine(String.Format("Simulation time = {0} {1} tau_0 = {2} tau_z = {3}",time, System.Environment.NewLine, tau_0, tau_z));
            file.WriteLine("Nodes information");
            int i = 0;
            int len = this.CurrentMap.Nodes.Count;
            foreach(Node n in this.CurrentMap.Nodes)
            {
                i++;
                file.WriteLine(String.Format("Node {0} {1}/{2}",n.NodeID,i,len));
                file.WriteLine(string.Format("     Population {0}", popMGR.GetPopulationOnNode(n)));
            }
            file.Close();
            file = new StreamWriter(directory + "ENVIRONMENT_CAR_LINKS" + fileName,true);
            file.WriteLine(String.Format("Simulation time = {0} {1} tau_0 = {2} tau_z = {3}", time, System.Environment.NewLine, tau_0, tau_z));
            file.WriteLine("Car links information");
            i = 0;
            len = this.CurrentMap.CarRoadLinks.Count;
            foreach(RoadLink rl in this.CurrentMap.CarRoadLinks)
            {
                i++;
                file.WriteLine(String.Format("Link {0} {1}/{2}",rl.Description,i,len));
                file.WriteLine(string.Format("     Flow {0}", popMGR.GetFlowOnLink(rl)));
            }
            file.Close();
            file = new StreamWriter(directory + "ENVIRONMENT_WALK_LINKS" + fileName,true);
            file.WriteLine(String.Format("Simulation time = {0} {1} tau_0 = {2} tau_z = {3}", time, System.Environment.NewLine, tau_0, tau_z));
            file.WriteLine("Walk links information");
            i = 0;
            len = this.CurrentMap.WalkRoadLinks.Count;
            foreach(RoadLink rl in this.CurrentMap.WalkRoadLinks)
            {
                i++;
                file.WriteLine(String.Format("Link {0} {1}/{2}",rl.Description,i,len));
                file.WriteLine(string.Format("     Flow {0}", popMGR.GetFlowOnLink(rl)));
            }
            file.Close();
        }
    }
}
